using System;
using System.Collections.Generic;
using System.Text;
using OpenComposite.Base.Designer;
using System.Drawing;
using System.Drawing.Drawing2D;
using OpenComposite.EII.Repository;
using OpenComposite.EII.Designer.Generic;

namespace OpenComposite.EII.Designer.SCA
{
	public class SystemSymbol : CollapsableSymbol, IRepositoryItemSymbol
	{
		#region Initialization
		public SystemSymbol()
		{
			init();
		}
		private void init()
		{
			this.BeginUpdate();

			//this.Name = "systemSymbol" + GetCount(typeof(SystemSymbol));
			this.Text = "System";

			this.NameTextBox.BorderVisibilityStyle = BorderVisibilityStyle.MouseOverAndFocus;
			this.NameTextBox.Width = this.NameTextBox.Width - 20;

			this.Size = new Size(500, 200);
			this.MinimumSize = new Size(70, 50);

			this.Border = BorderType.Rectangle;
			this.BorderColor = Color.OrangeRed;
			this.BorderStyle = System.Drawing.Drawing2D.DashStyle.Solid;
			this.BorderWidth = 2;

			this.BackColor = Color.FromArgb(64, Color.NavajoWhite);

			this.CollapsedBorderColor = Color.OrangeRed;
			this.CollapsedBackColor = Color.NavajoWhite;
			this.CollapsedBackColor2 = Color.NavajoWhite;
			this.ExpandedBorderColor = Color.OrangeRed;
			this.ExpandedBackColor = Color.FromArgb(64, Color.NavajoWhite);
			this.ExpandedBackColor2 = Color.FromArgb(64, Color.NavajoWhite);

			this.IsCollapsed = false;

			this.EndUpdate();
		}
		#endregion

		#region Public Members

		#region Override

		#region Properties
		public override bool CanFocused
		{
			get
			{
				return true;
			}
		}
		public override bool CanMove
		{
			get
			{
				return true;
			}
		}
		public override bool CanResize
		{
			get
			{
				return true;
			}
		}
		public override bool CanSelect
		{
			get
			{
				return true;
			}
		}
		public override bool IsContainer
		{
			get
			{
				return true;
			}
		}
		public override bool NoClip
		{
			get
			{
				return false;
			}
		}
		#endregion

		#region Drag & Drop
		public override object GetDragObject(Point location, System.Windows.Forms.MouseButtons button)
		{
			return this;
		}
		public override bool IsDropAllowed(object obj, Point location, System.Windows.Forms.MouseButtons button)
		{
			return this.IsDropAllowed(obj.GetType(), location, button);
		}
		public override bool IsDropAllowed(Type type, Point location, System.Windows.Forms.MouseButtons button)
		{
			if ( ( type == typeof(BusinessServices.BusinessServiceSymbol) ||
				   type == typeof(ITStructure.ITObjectSymbol) ||
				   type == typeof(BObjects.BOProcessSymbol) ||
				   type == typeof(BusinessProcess.ActivitySymbol) ||
				   type == typeof(ANDSymbol) ||
				   type == typeof(ORSymbol) ||
				   type == typeof(XORSymbol) ||
				   type == typeof(DomainSymbol) ||
				   type == typeof(SCA.ServiceModuleSymbol) ||
				   type == typeof(Selector.SelectorSymbol) ||
				   type == typeof(ExternalSymbol) ||
				   type == typeof(Generic.MappingSymbol) ) &&
				   button == System.Windows.Forms.MouseButtons.Left )
				return true;
			else if ( ( type == typeof(BusinessProcess.ActivitySymbol) ||
						type == typeof(ITStructure.ITObjectSymbol) ) &&
				button == System.Windows.Forms.MouseButtons.Right )
				return true;
			else
				return false;
		}
		public override void DropObject(object obj, Point location, System.Windows.Forms.MouseButtons button)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			if ( this.IsDropAllowed(obj, location, button) ) {
				if ( button == System.Windows.Forms.MouseButtons.Left ) {
					DesignerControl dc = null;
					if ( obj is RepositoryItemBase ) {
						dc = repSvc.CreateDesignerControl((RepositoryItemBase)obj);
					} else {
						dc = obj as DesignerControl;
					}
					if ( dc != null ) {
						dc.Location = this.PointToDesignerControlClient(location);
						this.Controls.Add(dc);
					}
				} else if ( button == System.Windows.Forms.MouseButtons.Right ) {
					this.DesignerViewControl.AddRoute((DesignerControl)obj, this);
				}
			}
		}
		#endregion

		public override void ReadXml(System.Xml.XmlReader reader)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			System.ComponentModel.BooleanConverter bc = new System.ComponentModel.BooleanConverter();
			while ( reader.Read() ) {
				switch ( reader.Name ) {
					case "DesignerControl":
						if ( reader.NodeType == System.Xml.XmlNodeType.EndElement )
							return;
						break;
					case "RepositorySystem":
						if ( reader.MoveToAttribute("id") && reader.ReadAttributeValue() )
							this.RepositoryItem = repSvc.GetItem(ItemType.System, int.Parse(reader.Value), false);
						if ( reader.MoveToAttribute("isRef") && reader.ReadAttributeValue() )
							this.IsReference = (bool)bc.ConvertFromString(reader.Value);
						break;
					case "DesignerControls":
						// read child controls
						ReadChildControls(reader);
						break;
					default:
						ReadStandardProperties(reader);
						break;
				}
			}
		}
		public override void WriteXml(System.Xml.XmlWriter writer)
		{
			System.ComponentModel.BooleanConverter bc = new System.ComponentModel.BooleanConverter();
			WriteStandardProperties(writer);

			if ( _system != null ) {
				writer.WriteStartElement("RepositorySystem");
				writer.WriteAttributeString("id", _system.ID.ToString());
				writer.WriteAttributeString("name", _system.Name);
				writer.WriteAttributeString("isRef", bc.ConvertToString(this.IsReference));
				writer.WriteEndElement();
			}

			WriteChildControls(writer);
		}

		public override object GetService(Type serviceType)
		{
			if ( _system != null )
				return _system.GetService(serviceType);
			else
				return base.GetService(serviceType);
		}
		#endregion

		#region IConnector Members

		public override Point GetRouteEnd(RouteDockDirection dock, Route route)
		{
			return base.GetRouteEnd(dock, route);
		}
		public override Point GetRouteStart(RouteDockDirection dock, Route route)
		{
			return base.GetRouteStart(dock, route);
		}

		#endregion

		#region IConnectorFactory Members

		public override bool CreateRouteEnd(DesignerControl controlStart, out IConnector connector,
			out System.Drawing.Drawing2D.LineCap cap, out System.Drawing.Drawing2D.CustomLineCap customcap,
			out RouteDockDirection dockStart, out RouteDockDirection dockEnd, out bool useEndConnectorAsRouteEnd)
		{
			bool ok = base.CreateRouteEnd(controlStart, out connector, out cap, out customcap, out dockStart, out dockEnd, out useEndConnectorAsRouteEnd);

			cap = System.Drawing.Drawing2D.LineCap.Custom;
			GraphicsPath path = new GraphicsPath();
			path.AddEllipse(-2.5f, -2.5f, 5f, 5f);
			customcap = new System.Drawing.Drawing2D.CustomLineCap(path, null);

			return ok;
		}
		public override bool CreateRouteStart(DesignerControl controlEnd, out IConnector connector,
			out System.Drawing.Drawing2D.LineCap cap, out System.Drawing.Drawing2D.CustomLineCap customcap,
			out RouteDockDirection dockStart, out RouteDockDirection dockEnd, out bool useStartConnectorAsRouteStart)
		{
			return base.CreateRouteEnd(controlEnd, out connector, out cap, out customcap, out dockStart, out dockEnd, out useStartConnectorAsRouteStart);
		}

		#endregion

		#region IRepositoryItemSymbol Members

		public bool SaveHierarchy
		{
			get { return true; }
		}

		private bool _isReference = false;
		public bool IsReference
		{
			get { return _isReference; }
			set { _isReference = value; }
		}

		public bool CanBeMainControl
		{
			get { return true; }
		}

		private Repository.RepositorySystem _system = null;
		public OpenComposite.EII.Repository.IRepositoryItem RepositoryItem
		{
			get
			{
				return _system;
			}
			set
			{
				_system = value as Repository.RepositorySystem;
				if ( _system != null ) {
					this.Text = _system.Name;
				}
			}
		}

		public void Load(int idRepository, int idDomain)
		{
			
		}

		public bool Save(int idRepository, int idDomain)
		{
			if ( _system == null )
				return false;

			return _system.Save();
		}

		public bool Delete(bool bAsk)
		{
			if ( _system == null )
				return true;

			return _system.Delete(bAsk);
		}

		#endregion
		
		#endregion

		#region Protected Members

		#region Override
		protected override void OnTextChanged(EventArgs e)
		{
			if ( _system != null ) {
				_system.Name = this.Text;
				this.Name = RepositoryService.GetIdentifier(this.Text);
			}
			base.OnTextChanged(e);
		}
		#endregion

		#endregion
	}
}
